#ifndef CHEAT_CODE_HEADER
#define CHEAT_CODE_HEADER

#pragma region LICENSE
//
// *LICENSE:
// Copyright (c) 2013 - 2014, "cheat_code" <cheat_code@aim.com>.
// Use the code is allowed under the Artistic License 2.0 terms,
// as specified in the LICENSE file distributed with this code,
// or available from: http://opensource.org/licenses/artistic-license-2.0
//
#pragma endregion LICENSE

#pragma region RELEASE_INFO
//////////////////////////////////////////////////////////////////////////////
//																			//
// Author: "The cheat_code" <cheat_code@aim.com>.							//
// Version: 1.1																//
// Released Date: 2/28/2013													//
//																			//
//////////////////////////////////////////////////////////////////////////////
#pragma endregion RELEASE_INFO

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>

#define CHEAT_CODE_NOPS	0
#define CHEAT_CODE_ORGINAL_DISABLE_BYTES 0
#define CHEAT_CODE_DEPENDENT 0

namespace Cheat_Code
{

class Cheat
{
public:
	typedef struct FLAG_STRUCT
	{
		enum __Flags
		{
			None = 0x00,
			EnableBytes_NOP = 0x01,
			#pragma region NO MIXING
			DisableBytes_NOP = 0x02,
			DisableBytes_Original = 0x04,
			DisableBytes_OriginalEx = 0x08,
			#pragma endregion
			AutoDisable = 0x10
		};
	} CheatFlags;
	
	Cheat( void ) :
		   Address( 0 ),
		   EnableBytes( 0 ),
		   DisableBytes( 0 ),
		   Enabled( false ),
		   Flags( CheatFlags::None )
	{ };
		   
	Cheat( __in unsigned long p_Address,
		   __in char* p_EnableBytes,
		   __in char* p_DisableBytes,
		   __in unsigned int p_EnableBytesLength,
		   __in unsigned int p_DisableBytesLength,
		   __in bool p_Enabled,
		   __in_opt unsigned int p_Flags = CheatFlags::None ) :
		   Address( p_Address ),
		   EnableBytes( p_EnableBytes ),
		   DisableBytes( p_DisableBytes ),
		   EnableBytesLength( p_EnableBytesLength ),
		   DisableBytesLength( p_DisableBytesLength ),
		   Enabled( p_Enabled ),
		   Flags( p_Flags )
	{
		   if( p_Flags ) FlagHandler( );
		   if( p_Enabled ) Enable( true );
	};
	
	~Cheat( void )
	{
		   if( Flags &( CheatFlags::AutoDisable )
			   && Enabled )
			   Enable( false );
		   
		   if( Flags &( CheatFlags::EnableBytes_NOP )
			   && EnableBytes != NULL )
			   delete [ ] EnableBytes;
			   
		   if( Flags &( CheatFlags::DisableBytes_NOP ) ||
			   Flags &( CheatFlags::DisableBytes_Original )
			   && DisableBytes != NULL )
			   delete [ ] DisableBytes;
	};
	
public:
	unsigned long Address;
	char* EnableBytes;
	char* DisableBytes;
	unsigned int EnableBytesLength;
	unsigned int DisableBytesLength;
	
private:
	unsigned int Flags;
	bool Enabled;
public:
	bool IsEnabled( void ) { return( Enabled ); };
	int Enable( __in bool p_Enable );
	
private:
	void FlagHandler( void );
};

namespace Util
{
	void WriteMemory( __in unsigned long Address,
					  __in char* Bytes,
					  __in unsigned int Length );

	void WriteNOP( __in unsigned long Address, __in unsigned int Length );
};

};

#endif // CHEAT_CODE_HEADER